/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.action;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.GroupRequest;
import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.uml2.uml.Lifeline;

import com.cea.papyrus.diagram.sequence.sedi.edit.LifelineEditPart;
import com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;

/**
 * Action to set or unset a lifeline decomposition.
 * 
 * @author frankd@ifi.uio.no
 */
public class LifelineDecomposeAction extends SelectionAction {

    public static final String ID = "no.uio.ifi.uml.sedi.decompose";

    public LifelineDecomposeAction(IWorkbenchPart part, int style) {
        super(part, style);
    }

    public LifelineDecomposeAction(IWorkbenchPart part) {
        super(part);
    }

    public void init() {
        super.init();
        setId(ID);
        setText("Decompose lifecycle");
    }

    @SuppressWarnings("unchecked")
    protected boolean calculateEnabled() {
        final List selectedObjects = getSelectedObjects();
        if (selectedObjects.isEmpty())
            return false;

        boolean decompose = false;
        for (final Object editPart : selectedObjects) {
            if (!(editPart instanceof LifelineEditPart))
                return false;
            final LifelineEditPart lifelinePart = (LifelineEditPart) editPart;
            final GraphElement lifelineView = (GraphElement) lifelinePart.getModel();
            final Lifeline lifeline = ModelUtil.<Lifeline> getSemantic(lifelineView);
            decompose |= lifeline.getDecomposedAs() != null;
        }

        setChecked(decompose);
        return true;
    }

    public void run() {
        execute(createDecomposeCommand(getSelectedObjects()));
    }

    @SuppressWarnings("unchecked")
    protected Command createDecomposeCommand(final List objects) {
        // verify that the command makes sense
        if (objects.isEmpty())
            return null;
        for (Object o : objects) {
            if (!(o instanceof EditPart))
                return null;
        }

        final GroupRequest decomposeReq =
                new GroupRequest("no.uio.ifi.uml.sedi.DecomposeLifelineRequest");
        decomposeReq.setEditParts(objects);
        final Map<String, Object> data = new HashMap<String, Object>();
        data.put("decompose", isChecked() ? Boolean.FALSE : Boolean.TRUE);
        decomposeReq.setExtendedData(data);

        final CompoundCommand compoundCmd = new CompoundCommand();
        // The cast is safe since we have verified that all items are EditParts
        for (EditPart editPart : (List<EditPart>) objects) {
            compoundCmd.add(editPart.getCommand(decomposeReq));
        }

        return compoundCmd;
    }
}
